package org.hackystat.iw.projectoverviewer.page.newproject;

import java.io.File;
import java.io.IOException;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.hackystat.iw.projectoverviewer.ProjectOverviewerApplication;
import org.hackystat.iw.projectoverviewer.jaxb.projects.Project;
import org.hackystat.iw.projectoverviewer.jaxb.projects.Projects;
import org.hackystat.iw.projectoverviewer.xml.XmlConverter;
import org.hackystat.iw.projectoverviewer.page.projects.ProjectsPage;
import org.hackystat.iw.projectoverviewer.sensordata.SensorDataCollector;
import org.hackystat.sensorbase.client.SensorBaseClient;
import org.hackystat.sensorbase.client.SensorBaseClientException;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebResponse;

/**
 * A forms for creating a new project.
 * The project name must match the project name defined in the hackystat. The username and password
 * must be the hackystat project owner's. The repository URL must be a Google project hosting URL.
 * 
 * @author Jianfei Liao
 * @author Nathan Britton
 */

public class NewProjectForm extends StatelessForm {
  
  /** Support serialization. */
  private static final long serialVersionUID = 1L;
  
  /** The project name. */
  private String projectName;
  
  /** The hackystat account name as the project owner. */
  private String ownerName;
  
  /** The hackystat account password. */
  private String password;
  
  /** The SVN URL for the project repository. */
  private String svnUrl;
  
  /**
   * Constructor.
   * Adds the fields for each required attribute, as well as a feedback panel for errors.
   * 
   * @param id Component ID, supplied by Wicket markup.
   * @param param Page parameters.
   */
  public NewProjectForm(String id, PageParameters param) {
    super(id);

    setModel(new CompoundPropertyModel(this));
    add(new TextField("projectName"));
    add(new TextField("ownerName"));
    add(new PasswordTextField("password"));
    add(new TextField("svnUrl"));
    add(new FeedbackPanel("errors"));
    
    if (param.getBoolean("NoProject")) {
      error("No project exists, please create one first.");
    }
  }
  
  /**
   * When the form is submiting, check for errors and try to create a new project.
   */
  @Override
  public void onSubmit() {
    ProjectOverviewerApplication app = (ProjectOverviewerApplication)getApplication();
    
    // check if any field is missing
    boolean hasAllFields = true;
    if (this.projectName == null) {
      hasAllFields = false;
      error("Project name is required.");
    }
    if (this.ownerName == null) {
      hasAllFields = false;
      error("Owner name is required.");
    }
    if (this.password == null) {
      hasAllFields = false;
      error("Password is required.");
    }
    if (this.svnUrl == null) {
      hasAllFields = false;
      error("The repository URL is required.");
    }
    
    if (hasAllFields) {
      try {
        // check if the owner is a valid hackystat user
        String host = app.getSensorBaseHost();
        SensorBaseClient client = new SensorBaseClient(host, this.ownerName, this.password);
        client.authenticate();
      }
      catch (SensorBaseClientException e) {
        error("Owner is not valid Hackystat user or password does not match.");
      }
      
      try {
        // check if the svn url is a valid google host url
        WebConversation wc = new WebConversation();
        WebResponse response = wc.getResponse(this.svnUrl);
        if (!response.getTitle().contains("Revision")) {
          error("The repository URL is not a valid Google host repository URL.");
        }
      }
      catch (Exception e) {
        error("Cannot connect to the repository URL.");
      }
      
      // if there is no error, create the project and go back to the home page
      if (!hasError() && createProject()) {
          // redirect to the projects page
          setResponsePage(ProjectsPage.class);
      }
      else {
        error("The project cannot be created. " +
              "A project with the same name already exists, or some information are invalid.");
      }
    }
    
  }
  
  /**
   * Creates a new project.
   * 
   * @return true if project is created, false otherwise.
   */
  private boolean createProject() {
    ProjectOverviewerApplication app = (ProjectOverviewerApplication)getApplication();
    Projects projects = app.getProjects();
    String userHome = System.getProperty("user.home");
    // master file for projects management
    File projectsFile = new File(userHome + "/.hackystat/projectoverviewer/projects.xml");
    
    // create new project and add it to the projects
    Project project = new Project();
    project.setProjectName(this.projectName);
    project.setOwner(this.ownerName);
    project.setPassword(this.password);
    project.setSvnUrl(this.svnUrl);
    for (Project existingProject : projects.getProject()) {
      if (existingProject.getProjectName().equalsIgnoreCase(this.projectName)) {
        return false;
      }
    }
    projects.getProject().add(project);
    
    try {
      // create the specific tm3 file and xml file for the new project
      File tm3File = new File(userHome + 
          "/.hackystat/projectoverviewer/" + this.projectName + ".tm3");
      File xmlFile = new File(userHome + 
          "/.hackystat/projectoverviewer/" + this.projectName + ".xml");
      tm3File.createNewFile();
      
      // initialize the data for the file
      SensorDataCollector collector = new SensorDataCollector(app.getSensorBaseHost(), 
                                                              this.ownerName, 
                                                              this.password);
      collector.getRepository(this.svnUrl, this.projectName);
      collector.write(tm3File, xmlFile);
    }        
    catch (IOException e) {
      e.printStackTrace();
      return false;
    }
    // write the projects.xml file with the new project added
    String packageName = "org.hackystat.iw.projectoverviewer.jaxb.projects";
    return XmlConverter.objectToXml(projects, projectsFile, packageName);
  }

  /**
   * Returns the project name.
   * 
   * @return The project name.
   */
  public String getProjectName() {
    return this.projectName;
  }
  
  /**
   * Sets the project name.
   * 
   * @param name The new project name.
   */
  public void setProjectName(String name) {
    this.projectName = name;
  }
  
  /**
   * Returns the owner name.
   * 
   * @return The owner name.
   */
  public String getOwnerName() {
    return this.ownerName;
  }
  
  /**
   * Sets the owner name.
   * 
   * @param name The new owner name.
   */
  public void setOwnerName(String name) {
    this.ownerName = name;
  }
  
  /**
   * Returns the password.
   * 
   * @return The password.
   */
  public String getPassword() {
    return this.password;
  }
  
  /**
   * Sets the password.
   * 
   * @param password The new password.
   */
  public void setPassword(String password) {
    this.password = password;
  }
  
  /**
   * Returns the repository URL.
   * 
   * @return The repository URL.
   */
  public String getSvnUrl() {
    return this.svnUrl;
  }
  
  /**
   * Sets the repository URL.
   * 
   * @param url The new repository URL.
   */
  public void setSvnUrl(String url) {
    this.svnUrl = url;
  }
}
